package com.mapperdb.builder.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import com.mapperdb.helper.Annt;
import com.mapperdb.helper.AnntHelper;
import com.mapperdb.mapping.Result;
import com.mapperdb.mapping.Result.Builder;
import com.mapperdb.type.JavaType;
import com.mapperdb.util.ReflectUtils;

/**
 * Result 注解 生成
 * @author Administrator
 *
 */
public class ResultBuilder {

	protected List<Result> results = new ArrayList<Result>();

	public ResultBuilder() {
	}

	public ResultBuilder(List<Method> methods) {
		parseResults(methods);
	}

	public static ResultBuilder use(List<Method> methods) {
		return new ResultBuilder(methods);
	}

	void parseResults(List<Method> methods) {
		for (Method method : methods) {
			this.parseResult(method);
		}
	}

	public void parseResult(Method method) {
		Class<? extends Annotation> resultAnnotationClass = AnntHelper.getResultAnnotationType(method);
		if (resultAnnotationClass == null) return;

		Annt annt = Annt.use(method, resultAnnotationClass);

		Boolean id = annt.get("id");
		String column = annt.get("column");
		String property = annt.get("property");
		Class<?> javaType = annt.get("javaType");
		JdbcType jdbcType = annt.get("jdbcType");
		Class<? extends TypeHandler<?>> typeHandler = annt.get("typeHandler");

		if (property.isEmpty()) property = ReflectUtils.getAttrName(method);
		if (column.isEmpty()) column = property;
		if (javaType == Void.TYPE) javaType = method.getReturnType();
		if (jdbcType == JdbcType.UNDEFINED) jdbcType = JavaType.forCode(javaType);

		Builder builder = Result.use()//
				.id(id)//
				.column(column)//
				.property(property)//
				.javaType(javaType)//
				.jdbcType(jdbcType)//
				.typeHandler(typeHandler);

		if (id) {// selectKey before
			Class<? extends Annotation> selectKeyAnnotationClass = AnntHelper.getSelectKeyAnnotationType(method);
			if (selectKeyAnnotationClass != null) {
				Annt selectKeyAnnotation = Annt.use(method, selectKeyAnnotationClass);
				builder.before(selectKeyAnnotation.get("before", boolean.class));
			}
		}
		results.add(builder.build());
	}

	public List<Result> getResults() {
		return results;
	}
}
